
package com.scs.application.modules.upms.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.scs.application.core.exceptions.BusinessException;
import com.scs.application.core.service.TreeServiceImpl;
import com.scs.application.core.utils.StringUtils;
import com.scs.application.core.utils.UserUtils;
import com.scs.application.modules.upms.entity.Office;
import com.scs.application.modules.upms.mapper.OfficeMapper;
import com.scs.application.modules.upms.request.OfficeQueryRequest;
import com.scs.application.modules.upms.security.UserPrincipal;
import com.scs.application.modules.upms.service.OfficeService;
import com.scs.application.modules.upms.vo.OfficeVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 机构 service 实现
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class OfficeServiceImpl extends TreeServiceImpl<OfficeMapper, Office> implements OfficeService {

    @Override
    public List<Office> list(OfficeQueryRequest request) {
        List<Office> list = this.list(Wrappers.<Office>query()
                .like(StringUtils.isNotBlank(request.getName()), "name", request.getName())
                .eq(StringUtils.isNotBlank(request.getParentId()), "parent_id", request.getParentId())
                .orderByAsc("sort")
        );
        return list;
    }

    @Override
    public IPage<OfficeVO> page(OfficeQueryRequest request) {
        UserPrincipal user = UserUtils.currentUser();
        if (!user.isAdmin() && StringUtils.isNotBlank(user.getOfficeId())) {
//            request.setOfficeIds(String.join(",", getOfficeParents(oAuthUser.getOfficeId(),true)));
            request.setOfficeIds(String.format(",%s,", user.getOfficeId()));
            if (request.getParentId().equals("0")) {
                request.setParentId("");
            }
        }
        return this.baseMapper.page(request.getPage(), request);
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public Office addForSupplier(OfficeVO vo) {

        Office office = new Office();
        BeanUtils.copyProperties(vo, office);
        office.setType(Office.TYPE_SUPPLIER).setParentId(getTopSupplierId());

        preSave(office);

        this.saveCascadeById(office);

        return office;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Office addForHospital(OfficeVO vo) {

        Office office = new Office();
        BeanUtils.copyProperties(vo, office);
        office.setType(Office.TYPE_HOSPITAL).setParentId(getTopHospitalId());
        preSave(office);

        this.saveCascadeById(office);

        return office;
    }

    /**
     * 机构的父级Ids(不包括0和一级机构【供应商机构、医院机构】)
     *
     * @param officeId
     * @return
     */
    @Override
    public List<String> getOfficeParents(String officeId, boolean includeSelf) {
        Office office = this.getById(officeId);
        List<String> userIds = new ArrayList<>();
        if (office != null) {
            if (StringUtils.isNotBlank(office.getParentIds())) {
                userIds = Arrays.asList(office.getParentIds().split(",")).stream()
                        .filter(
                                id -> {
                                    Office offece = this.getById(id);
                                    if (offece == null) {
                                        offece = new Office();
                                    }
                                    return  !StringUtils.isWhitespace(id) && !"0".equals(id) && !"0".equals(offece.getParentId());
                                }

                        )
                        .collect(Collectors.toList());
            }
        }

        if (includeSelf) {
            userIds.add(officeId);
        }
        return userIds;
    }

    /**
     * 获取顶级医院机构
     *
     * @return
     */
    private String getTopHospitalId() {
        QueryWrapper<Office> wrapper = Wrappers.query();
        wrapper.eq("code", "hospital")
                .eq("parent_id", 0);

        Office office = this.getOne(wrapper);
        if (office == null) {
            log.warn("未找到可挂靠的医院顶级机构，请先手动进行添加code为hospital的顶级机构");
            throw new BusinessException("系统数据错误，请联系管理员");
        }
        return office.getId();
        // todo 依据标识查询？
        // return "1158984866549841921";
    }

    private String getTopSupplierId() {
        QueryWrapper<Office> wrapper = Wrappers.query();
        wrapper.eq("code", "supplier")
                .eq("parent_id", 0);

        Office office = this.getOne(wrapper);
        if (office == null) {
            log.warn("未找到可挂靠的供应商顶级机构，请先手动进行添加code为supplier的顶级机构");
            throw new BusinessException("系统数据错误，请联系管理员");
        }
        return office.getId();
//        return "1158984645182865410";
    }

}
